
#include <opencv4/opencv2/opencv.hpp>
#include <string>
#include <iostream>
#include "calibration.h"
#include "undistort.h"
#include<yaml-cpp/yaml.h>
using namespace std;
using namespace cv;

int main(int argc, char** argv)
{
    CCalibration::InitLogFile("calibration.log");
    if (argc < 2) {
        std::cout << "Usage: " << argv[0] << " <图片路径未输入！>" << std::endl;
        CCalibration::Log("Usage: " + string(argv[0]) + " <图片路径未输入！>");
        CCalibration::CloseLogFile();
        return 1;
    }
    std::ifstream file("../config.yaml");
    if(file.is_open() == false) 
    {
        //std::cout << "config.yaml文件打开失败！" << std::endl;
        CCalibration::Log("config.yaml文件打开失败！");
        CCalibration::CloseLogFile();
        return 1;
    }

    YAML::Node node = YAML::Load(file);
    file.close();
    //棋盘格行列
    int chess_row = node["chess_row"].as<int>();
    int chess_col = node["chess_col"].as<int>();
    //方格大小
    int square = node["square_size"].as<int>();
    //是否详细输出数据文档
    bool detail_output = node["output_detail"].as<bool>();
    //是否降采样
    bool downsample = node["downsample"].as<bool>();
    //是否显示绘制角点过程
    bool show_draw = node["show_draw"].as<bool>();
    //是否实现畸变矫正
    bool undistort = node["undistort"].as<bool>();
    //图片路径保存文件与输出文件
    //std::string image_path = node["image_path"].as<std::string>();
    string image_path = "image_path.txt";
    std::string camera_matrix_file = node["camera_matrix_file"].as<std::string>();
    //读取文件后缀名
    //std::string suffix = node["image_suffix"].as<std::string>();
    std::string suffix = ".jpg";
    std::string camera_type = node["camera_type"].as<std::string>();
        
    const char* path_to_images = argv[1];
    string patternImgPath(path_to_images);  //标定板图像存放文件夹路径（标定板图像文件名按照0.jpg, 1.jpg...如此命名）；
    Size boardSize = Size( chess_row-1,chess_col-1 );  //标定板内角点行和列个数
    string calibResultPath = "camera_result_detail.txt";  //摄像机标定内部参数文件保存路径，fx, fy, cx,cy, 以及畸变系数(k1,k2,p1,p2,k3 或者 k1,k2,k3,k4);
    std::cout<<"标定启动......"<<std::endl;
    CCalibration::Log("标定启动......");
    CCalibration calibration(patternImgPath, image_path, camera_matrix_file,boardSize,suffix,  square, calibResultPath, camera_type, detail_output,downsample, show_draw);
    calibration.run();
    if(undistort)
    {
        //cout<<"开始矫正......"<<endl;
        CCalibration::Log("开始矫正......");
        std::string srcImgPath = node["test_image_path"].as<std::string>();  //相机拍摄测试图片保存路径，用来测试标定和畸变校正结果；
        CUndistort undistort(srcImgPath, camera_matrix_file,camera_type);
        undistort.run();
        CCalibration::Log("矫正完成......");
        //cout<<"矫正完成......"<<endl;
    }
    CCalibration::Log("标定结束......");
    CCalibration::CloseLogFile();
    std::cout<<"标定结束......"<<std::endl;
    return 0;
}